home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / front.lha / front / src / TokenTab.mi < prev    next >
Text File  |  1992-08-18  |  9KB  |  342 lines

  1. (* map tokens to internal representation *)
  2.  
  3. (* $Id: TokenTab.mi,v 2.2 1992/08/07 15:13:51 grosch rel $ *)
  4.  
  5. (* $Log: TokenTab.mi,v $
  6.  * Revision 2.2  1992/08/07  15:13:51  grosch
  7.  * allow several scanner and parsers; extend module Errors
  8.  *
  9.  * Revision 2.1  1991/11/21  14:47:50  grosch
  10.  * new version of RCS on SPARC
  11.  *
  12.  * Revision 2.0  91/03/08  18:26:41  grosch
  13.  * turned tables into initialized arrays (in C)
  14.  * moved mapping tokens -> strings from Errors to Parser
  15.  * changed interface for source position
  16.  * 
  17.  * Revision 1.2  90/06/11  18:45:44  grosch
  18.  * layout improvements
  19.  * 
  20.  * Revision 1.1     89/01/26  19:03:26  vielsack
  21.  * better position handling for nonterminals
  22.  * 
  23.  * Revision 1.0     88/10/04  14:27:23  vielsack
  24.  * Initial revision
  25.  * 
  26.  *)
  27.  
  28. IMPLEMENTATION MODULE TokenTab;
  29.  
  30. (* Umsetzung der Vokabularzeichen (tIdent) in eine interne Darstellung
  31.    (Vocabulary). Zusaetzlich besteht die Moeglichkeit, weitere Information
  32.    ueber ein Vokabularzeichen aufzunehmen (Special). *)
  33.  
  34. FROM SYSTEM    IMPORT ADR, ADDRESS;
  35. FROM Strings    IMPORT ArrayToString, tString;
  36. FROM Idents    IMPORT MakeIdent,tIdent,GetString;
  37. FROM Errors    IMPORT eFatal, eRestriction, eIdent, eString, eInternal, ErrorMessageI;
  38. FROM Positions    IMPORT NoPosition;
  39.  
  40. CONST
  41.     eNoIntCode        = 25;
  42.     eTokenOverflow    = 26;
  43.  
  44.      (* Von der Symboltabelle duerfen nur Werte bis zu dieser Groesse geliefert werden. *)
  45.  
  46.     MaxTokens        = cMAXNonTerm;
  47.     NoValue        = MaxTokens;
  48.     DefValue        = MaxTokens + 1;
  49.  
  50. TYPE Symbols        = [0..MaxTokens];
  51.  
  52. VAR 
  53.     (* Unter ExToInt[i] steht die interne Darstellung des Eintrags i der Symboltabelle *)
  54.  
  55.     ExToInt    : ARRAY Symbols OF Vocabulary;
  56.  
  57.     (* Unter IntToEx[i] steht der Eintrag in der Symboltabelle, die
  58.        der internen Darstellung i entspricht *)
  59.     
  60.     ExToPos    : ARRAY Symbols OF PosType;
  61.     ExPosSet    : ARRAY Symbols OF BOOLEAN;
  62.  
  63.     (* Fuer jedes Symbol wird die kleinste Position an der es auftritt festgehalten *)
  64.  
  65.     IntToEx    : ARRAY Vocabulary OF Symbols; 
  66.  
  67.     (* Eintrag der aktuellen Prioritaet eines Vocabularzeichens. Auf 0 initialisiert. *)
  68.  
  69.     PrioField    : ARRAY Vocabulary OF Prio;
  70.  
  71.     (* DefaultVoc enthaelt das zuletzt und damit hoechste mit Default-
  72.        nummer eingetragene Terminal *)
  73.  
  74.     DefaultVoc    : [0..cMAXTerm+1];
  75.     i        : CARDINAL;
  76.  
  77.     GetNextNonTerminalAllowed    : BOOLEAN;
  78.     Actualnt    : [MINNonTerm..cMAXNonTerm];
  79.  
  80.     (* Variablen fuer main section *)
  81.     ter        : Terminal;
  82.     err        : TokenError;
  83.     s        : tString;
  84.     pos        : PosType;
  85.  
  86.   PROCEDURE MakeTerm (sym: tIdent; VAR ter: Terminal; VAR Error: TokenError; pos: PosType);
  87.   
  88.   (* Fuege sym als NEUES Terminal in TokenTab mit vorgegebener Codierung
  89.      ter ein. Falls s bereits in der TokenTab steht, wird der alte Code
  90.      zurueckgeliefert und Error auf SymbolExists gesetzt.
  91.      Error = CodeExists, falls der angegebene Code bereits vergeben ist . *)
  92.  
  93.   BEGIN
  94.     IF sym > cMAXNonTerm THEN
  95.       Error := OutOfRange;
  96.     ELSIF ExToInt[sym] <> NoValue THEN 
  97.       (* Es wurde schon ein Eintrag  mit vorgenommen *)
  98.       Error:= SymbolExists;
  99.       ter  := ExToInt[sym];
  100.     ELSIF IntToEx[ter] <> NoValue THEN
  101.       (* Es wurde einEintrag mit MakeDefTerm gemacht *)
  102.       Error := CodeExists;
  103.     ELSE
  104.       ExToInt[sym]    := ter;
  105.       IntToEx[ter]    := sym;
  106.       Error        := NoError;
  107.       ExToPos[sym]    := pos;
  108.       IF ter > MAXTerm THEN
  109.     MAXTerm := ter;
  110.       END;
  111.     END;
  112.   END MakeTerm;
  113.  
  114.   PROCEDURE MakeDefTerm (VAR sym: tIdent; VAR Error: TokenError; pos: PosType);
  115.  
  116.   (* Fuege sym als NEUES Terminal in TokenTab ohne interne Codierung
  117.      ein. Die Codierung muss nach Abschluss aller Eintraege in die
  118.      TokenTab mit CompleteDefTerm nachgeholt werden. 
  119.      Falls s bereits in der TokenTab steht, wird der alte Code zurueck-
  120.      geliefert und Error auf SymbolExists gesetzt. *)
  121.  
  122.   BEGIN
  123.     IF (ExToInt [sym] <> NoValue) THEN
  124.      (* sym steht bereits in der TokenTab  *) 
  125.       Error := SymbolExists;
  126.     ELSE
  127.       ExToInt[sym]     := DefValue;
  128.       Error           := NoError;
  129.       ExToPos[sym]     := pos;
  130.     END;
  131.   END MakeDefTerm;
  132.  
  133.   PROCEDURE CompleteDefTerm (sym: tIdent; VAR Error: TokenError);
  134.  
  135.   (* Traegt die interne Codierung fuer bereits mit MakeDefTerm eingetragene
  136.      Terminale nach .Moegliche Fehler:
  137.      Error = NotExists       Noch gar nicht eingetragen
  138.          CodeExists       Schon vollstaendig eingetragen
  139.          NonTerm   sym ist Codierung fuer Nichtterminal; *)
  140.   
  141.   BEGIN
  142.     IF ExToInt[sym] = NoValue THEN
  143.       (* Symbol noch gar nicht eingetragen *)
  144.       Error := NotExists;
  145.     ELSIF ExToInt[sym] <> DefValue THEN
  146.       (* Symbol schon vollstaendig eingetragen *)
  147.       IF GetTokenType(ExToInt[sym]) = NonTerm THEN
  148.     Error := NotTerm;
  149.       ELSE
  150.     Error := CodeExists;
  151.       END;
  152.     ELSE
  153.       (* alles ok *)
  154.       NextDefault; (* DefaultVoc weiterschalten *)
  155.       IF DefaultVoc <= cMAXTerm THEN
  156.     ExToInt[sym] := DefaultVoc;
  157.     IntToEx[DefaultVoc] := sym;
  158.     IF DefaultVoc > MAXTerm THEN
  159.        MAXTerm := DefaultVoc;
  160.     END;
  161.     Error           := NoError;
  162.       ELSE
  163.     ErrorMessageI(eTokenOverflow,eRestriction,NoPosition,eIdent,ADR(sym));
  164.       END;
  165.     END;
  166.   END CompleteDefTerm;
  167.   
  168.   PROCEDURE MakeVoc (sym: tIdent; symPos: PosType): Vocabulary;
  169.  
  170.   (* falls s bereits vorhanden:
  171.     die Codierung von sym wird zurueckgeliefert
  172.      sonst:
  173.     s wird als NichtTerminal in die TokenTab eingetragen und die
  174.     Codierung zurueckgeliefert.
  175.      Bei Tabellenueberlauf wird Error = TokenOverflow. *)
  176.  
  177.   BEGIN
  178.     IF ExToInt[sym] = DefValue THEN
  179.       ErrorMessageI(eNoIntCode,eFatal,symPos, eIdent, ADR(sym));
  180.     ELSIF
  181.       ExToInt[sym] # NoValue THEN (* s bereits vorhanden *)
  182.  
  183.       (* ist neue Position kleiner als bisher bekannte? *)
  184.  
  185.       IF (ExToPos[sym].Line > symPos.Line) OR
  186.      (   (ExToPos[sym].Line = symPos.Line)
  187.      AND (ExToPos[sym].Column > symPos.Column) ) THEN
  188.     
  189.     (* ist neue Position gueltig? *)
  190.  
  191.     IF (symPos.Line # 0) AND (symPos.Column # 0) THEN
  192.  
  193.       (* halte Positon fuer evtl. Fehlermeldungen fest *)
  194.  
  195.       ExToPos[sym] := symPos
  196.  
  197.     END;
  198.       END;
  199.  
  200.       RETURN ExToInt[sym];
  201.     ELSE
  202.       (* Noch kein Eintrag *)
  203.       INC(MAXNonTerm);
  204.       IF MAXNonTerm >= MaxTokens THEN
  205.     ErrorMessageI (eTokenOverflow,eRestriction,symPos, eIdent, ADR(sym));
  206.       ELSE
  207.     ExToPos[sym] := symPos;
  208.     ExToInt[sym] := MAXNonTerm;
  209.     IntToEx[MAXNonTerm] := sym ;
  210.     RETURN MAXNonTerm;
  211.       END;
  212.     END;
  213.   END MakeVoc;
  214.  
  215.   PROCEDURE SetNontermPos (sym: tIdent; pos: PosType);
  216.  
  217.   (* setze Position eines Nichtterminals *)
  218.  
  219.   BEGIN
  220.     IF NOT ExPosSet [sym] THEN
  221.       ExToPos [sym] := pos;
  222.       ExPosSet [sym] := TRUE;
  223.     END;
  224.   END SetNontermPos;
  225.  
  226.   PROCEDURE GetTokenType (voc: Vocabulary): TokenType;
  227.  
  228.   (* liefert den Typ des Tokens voc zurueck *)
  229.   BEGIN
  230.     IF (IntToEx[voc] = NoValue) OR (voc >= MaxTokens) THEN
  231.       RETURN None;
  232.     ELSIF voc <= cMAXTerm THEN
  233.       RETURN Term;
  234.     ELSE
  235.       RETURN NonTerm;
  236.     END;
  237.   END GetTokenType;
  238.  
  239. PROCEDURE SymbolToToken (sym: tIdent; VAR Error: TokenError): Vocabulary;
  240.   
  241.   (* liefert die zum SymboltabellenEintrag sym gehoerige interne Darstellung*)
  242.   (* Moegliche Fehler:
  243.      Error = NotExists      Es existiert ueberhaupt kein Eintrag
  244.      Error = NoIntCode      Code muss noch mit CompleteDefToken eingetragen
  245.               werden.
  246.      Error = NoError      Alles in Ordnung    *)
  247.  
  248. BEGIN 
  249.   IF ExToInt[sym] = NoValue THEN
  250.     Error := NotExists;
  251.   ELSIF ExToInt[sym] = DefValue THEN
  252.     Error := NoIntCode;
  253.   ELSE
  254.     Error := NoError;
  255.   END;
  256.   RETURN ExToInt[sym];
  257. END SymbolToToken;
  258.  
  259. PROCEDURE  TokenToSymbol (voc: Vocabulary; VAR Error: TokenError):tIdent;
  260.   
  261.   (* liefert die zum TokenTabeintrag voc gehoerige Darstellung
  262.      in der Symboltabelle *)
  263.   (* Moegliche Fehler:
  264.      Error = NotExists      Es existiert ueberhaupt kein Eintrag
  265.               werden.
  266.      Error = NoError      Alles in Ordnung    *)
  267.  
  268. BEGIN 
  269.   IF IntToEx[voc] = NoValue THEN
  270.     Error := NotExists;
  271.   ELSE
  272.     Error := NoError;
  273.   END;
  274.   RETURN IntToEx[voc];
  275. END TokenToSymbol;
  276.   
  277. PROCEDURE GetTokenPos (voc: Vocabulary; VAR pos: PosType);
  278. VAR sym: tIdent;
  279. BEGIN
  280.   sym := IntToEx[voc];
  281.   IF sym = NoValue THEN
  282.     pos.Line := 0;
  283.     pos.Column := 0;
  284.   ELSE
  285.     pos := ExToPos [sym];
  286.   END;
  287. END GetTokenPos;
  288.   
  289.   PROCEDURE PutPrio (voc: Vocabulary; p: Prio);
  290.  
  291.   (* Setzen der Prioritaet von voc auf p *)
  292.   BEGIN
  293.     PrioField[voc] := p;
  294.   END PutPrio;
  295.  
  296.   PROCEDURE GetPrio (voc: Vocabulary):Prio;
  297.  
  298.   (* liefert die mit PutPriority eingetragene Prioritaet von voc.
  299.      Ist nichts eingetragen, wird 0 zurueckgegeben. *)
  300.   BEGIN
  301.     RETURN PrioField[voc];
  302.   END GetPrio;
  303.  
  304.   PROCEDURE NextDefault;
  305.   BEGIN
  306.     WHILE (IntToEx[DefaultVoc] <> NoValue) AND
  307.       (DefaultVoc < (cMAXTerm+1)) DO
  308.       INC(DefaultVoc);
  309.     END;
  310.   END NextDefault;
  311.  
  312.   PROCEDURE InitTokenTable;
  313.   BEGIN
  314.     GetNextNonTerminalAllowed := FALSE;
  315.     FOR i := 0 TO MaxTokens DO
  316.       IntToEx[i] := NoValue;
  317.       ExToInt[i] := NoValue;
  318.       ExPosSet[i] := FALSE;
  319.       PrioField[i] := 0;
  320.     END;
  321.     DefaultVoc := 1;
  322.     MAXNonTerm := cMAXTerm;
  323.     ArrayToString ('_EndOfFile', s);
  324.     ter := EndOfToken;
  325.     pos.Line := 0;
  326.     pos.Column := 0;
  327.     MakeTerm (MakeIdent(s),ter,err,pos);
  328.     IF err # NoError THEN
  329.       ERROR ('TokenTab.InitTokenTable');
  330.     END;
  331.     MAXTerm := 0;
  332.   END InitTokenTable;
  333.  
  334.   PROCEDURE ERROR (a: ARRAY OF CHAR);
  335.   VAR s: tString;
  336.   BEGIN
  337.     ArrayToString (a, s);
  338.     ErrorMessageI (eInternal, eFatal, NoPosition, eString, ADR (s));
  339.   END ERROR;
  340.  
  341. END TokenTab.
  342.